﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Luminal
{
    public struct ImageRegion2D : IEquatable<ImageRegion2D>
    {
        public int X, Y;
        public int Width, Height;

        public ImageRegion2D(int x, int y, int width, int height)
        {
            X = x;
            Y = y;
            Width = width;
            Height = height;
        }

        public override bool Equals(object obj)
        {
            if (obj is ImageRegion2D)
                return Equals((ImageRegion2D)obj);
            else
                throw new InvalidCastException("Object is not of type Luminal.ImageRegion2D");
        }

        public bool Equals(ImageRegion2D other)
        {
            return X == other.X &&
                Y == other.Y &&
                Width == other.Width &&
                Height == other.Height;
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() ^ Y.GetHashCode() ^ Width.GetHashCode() ^ Height.GetHashCode();
        }

        public static bool operator ==(ImageRegion2D ls, ImageRegion2D rs)
        {
            return ls.Equals(rs);
        }

        public static bool operator !=(ImageRegion2D ls, ImageRegion2D rs)
        {
            return !ls.Equals(rs);
        }

        public override string ToString()
        {
            return string.Format("X: {0}, Y: {1}, Width: {2}, Height: {3}", X, Y, Width, Height);
        }

        static ImageRegion2D zero = new ImageRegion2D(0, 0, 0, 0);
        public static ImageRegion2D Zero { get { return zero; } }
    }

    public struct ImageRegion3D : IEquatable<ImageRegion3D>
    {
        public int X, Y, Z;
        public int Width, Height, Depth;

        public ImageRegion3D(int x, int y, int z, int width, int height, int depth)
        {
            X = x;
            Y = y;
            Z = z;
            Width = width;
            Height = height;
            Depth = depth;
        }

        public override bool Equals(object obj)
        {
            if (obj is ImageRegion3D)
                return Equals((ImageRegion3D)obj);
            else
                throw new InvalidCastException("Object is not of type Luminal.ImageRegion2D");
        }

        public bool Equals(ImageRegion3D other)
        {
            return X == other.X &&
                Y == other.Y &&
                Z == other.Z &&
                Width == other.Width &&
                Height == other.Height &&
                Depth == other.Depth;
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() ^
                Y.GetHashCode() ^
                Z.GetHashCode() ^
                Width.GetHashCode() ^
                Height.GetHashCode() ^
                Depth.GetHashCode();
        }

        public static bool operator ==(ImageRegion3D ls, ImageRegion3D rs)
        {
            return ls.Equals(rs);
        }

        public static bool operator !=(ImageRegion3D ls, ImageRegion3D rs)
        {
            return !ls.Equals(rs);
        }

        public override string ToString()
        {
            return string.Format("X: {0}, Y: {1}, Z: {3}, Width: {3}, Height: {4}, Depth: {5}", X, Y, Z, Width, Height, Depth);
        }

        static ImageRegion3D zero = new ImageRegion3D(0, 0, 0, 0, 0, 0);
        public static ImageRegion3D Zero { get { return zero; } }
    }
}
